package com.athui.utils.explorer;

import com.athui.bean.metadata.ColumnMetaData;
import com.athui.bean.config.DataType;
import com.athui.enums.DataRegularEnums;
import com.athui.utils.common.RegexMatchUtils;
import org.apache.flink.shaded.guava30.com.google.common.hash.BloomFilter;

import java.math.BigDecimal;
import java.util.regex.Matcher;

/**
 * @description: TODO 数据探查
 * @autor: zhangzhonghui
 * @create: 2024-08-03 20:57
 * @Version: 1.0
 */
public class DataExplorer {

    private ColumnMetaData columnMetaData;
    private Object val;

    private Boolean valIsNull=false;


    public DataExplorer(ColumnMetaData columnMetaData,Object val)  {
        try {
            this.columnMetaData = (ColumnMetaData)columnMetaData.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        this.val = val;
    }

    /**
     * @description: TODO 总数统计
     * @author: 阿辉大人
     * @return: com.athui.utils.explorer.DataExplorer
     * @create: 2024/8/3 21:05
     * @version: 1.0
    **/
    public DataExplorer totalCount(){
        // 总条数
        columnMetaData.setTotalCount(1L);
        return this;
    }

    /**
     * @description: TODO 探索空值
     * 如果当前值为null，增加列元数据中的空值计数，并标记valIsNull为true
     * 主要用于在数据探索过程中记录和标记空值信息
     * @author: 阿辉大人
     * @return: com.athui.utils.explorer.DataExplorer
     * @create: 2024/8/3 21:02
     * @version: 1.0
    **/
    public DataExplorer nullCount(){
        if (val == null){
            columnMetaData.setNullValueCount(1L);
            valIsNull = true;
        }
        return this;
    }

    public DataExplorer repeatCount(BloomFilter bloomFilter){
        // 重复判断
        String hashCode = columnMetaData.getColumnCode() + "=" + (val == null ? "null".hashCode() : val.hashCode());
        // 布隆过滤器特性：说存在不一定存在，说不存在一定就不存在。
        if (!bloomFilter.test(hashCode)) {
            columnMetaData.setNotRepeatValueCount(1L);
        }
        bloomFilter.put(hashCode);
        return this;
    }



    /**
     * @description: TODO 文本数据探索
     * 需要是文本类型，并且不为null
     * @author: 阿辉大人
     * @return: com.athui.utils.explorer.DataExplorer
     * @create: 2024/8/3 21:15
     * @version: 1.0
    **/
    public DataExplorer textExplorer(){
        boolean isText = DataType.TEXT.equals(columnMetaData.getTypeLabel());
        if ( !valIsNull && isText){
            String value = val.toString().trim();
            int length = value.length();
            // 字符串长度统计
            columnMetaData.setTextMinLength((long) length);
            columnMetaData.setTextMaxLength((long) length);

            // 文本规范规则匹配
            if(columnMetaData.getTextPattern() != null){
                Matcher matcher = columnMetaData.getTextPattern().matcher(value);
                if(!matcher.matches()){
                    // 记录不合格数据的 次数
                    columnMetaData.setIllegalityValueCount(1L);
                }
            }

            // 空值检查
            if (val.toString().trim().length() == 0){
                columnMetaData.setEmptyValueCount(1L);
            }

            // 关注数据范围，计算为true的数据
            if(columnMetaData.getInvolvedRange() !=null && !RegexMatchUtils.inDataRange(value,columnMetaData.getInvolvedRange())){
                columnMetaData.setInvolvedValueCount(1L);
            }

        }


        return this;
    }

    /**
     * @description: TODO 数值类型探索
     * @author: 阿辉大人
     * @return: com.athui.utils.explorer.DataExplorer
     * @create: 2024/8/22 13:09
     * @version: 1.0
    **/
    public DataExplorer numericalExplorer(){
        if (DataType.NUMERICAL.equals(columnMetaData.getTypeLabel())) {
            String value = String.valueOf(val).trim();
            // 判断是否为数字
            boolean isNumber = DataRegularEnums.NUMERICAL_IS_NUMERICAL
                    .getValue()
                    .matcher(value)
                    .matches();

            if (isNumber) {
                BigDecimal number = new BigDecimal(value);
                // 最大最小值 统计illegalityValueCount
                columnMetaData.setNumericalMaxValue(number);
                columnMetaData.setNumericalMinValue(number);

                // 0 值统计
                if((new BigDecimal(value)).compareTo(BigDecimal.ZERO) == 0){
                    columnMetaData.setZeroValueCount(1L);
                }

                // 数值范围
                if((columnMetaData.getNumericalRange() !=null ) && (!RegexMatchUtils.inDataRange(new BigDecimal(value),columnMetaData.getNumericalRange()))){
                    // 记录不合格数据的 次数
                    columnMetaData.setIllegalityValueCount(1L);
                }

                // 关注数据范围，计算为true的数据
                if(columnMetaData.getInvolvedRange() !=null && !RegexMatchUtils.inDataRange(new BigDecimal(value),columnMetaData.getInvolvedRange())){
                    columnMetaData.setInvolvedValueCount(1L);
                }

            }else{
                // 将非数值类型值标记为无效值
                columnMetaData.setInvalidValueCount(1L);
            }
        }

        return this;
    }

    public  ColumnMetaData build(){
        return this.columnMetaData;
    }

}
